import type { AxiosResponse, AxiosRequestConfig } from 'axios';
import axios from 'axios';
import JwtService from '@/core/services/JwtService';
import type { ApiResponse, ApiError } from '@/types/common/api';

/**
 * 基础HTTP服务类
 * 封装axios请求，提供类型安全的API调用
 */
export class HttpService {
  private static instance: HttpService;
  private baseURL: string;

  private constructor() {
    this.baseURL = import.meta.env.VITE_APP_API_URL || '';
    this.setupInterceptors();
  }

  public static getInstance(): HttpService {
    if (!HttpService.instance) {
      HttpService.instance = new HttpService();
    }
    return HttpService.instance;
  }

  private setupInterceptors(): void {
    // 请求拦截器
    axios.interceptors.request.use(
      (config) => {
        const token = JwtService.getToken();
        if (token) {
          config.headers.Authorization = `Token ${token}`;
        }
        config.headers.Accept = 'application/json';
        config.baseURL = this.baseURL;
        return config;
      },
      (error) => {
        return Promise.reject(error);
      },
    );

    // 响应拦截器
    axios.interceptors.response.use(
      (response: AxiosResponse) => {
        return response;
      },
      (error) => {
        const apiError: ApiError = {
          message: error.response?.data?.message || error.message,
          code: error.response?.status,
          details: error.response?.data,
        };
        return Promise.reject(apiError);
      },
    );
  }

  async get<T>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    const response = await axios.get<T>(url, config);
    return response.data as ApiResponse<T>;
  }

  async post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    const response = await axios.post<T>(url, data, config);
    return response.data as ApiResponse<T>;
  }

  async put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    const response = await axios.put<T>(url, data, config);
    return response.data as ApiResponse<T>;
  }

  async delete<T>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>> {
    const response = await axios.delete<T>(url, config);
    return response.data as ApiResponse<T>;
  }

  async query<T>(url: string, params?: any): Promise<ApiResponse<T>> {
    const response = await axios.get<T>(url, { params });
    return response.data as ApiResponse<T>;
  }
}

// 导出单例实例
export const httpService = HttpService.getInstance();
